package aole.visq.draw;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.Toolkit;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.beans.Transient;

import javax.swing.JComponent;

public class DrawCanvas extends JComponent {
	private static final long	serialVersionUID	= 1L;
	private DrawApp				app;
	// image operation for onion skin
	private final float[]		scales				= { 1f, 1f, 1f, 0.2f };
	private final float[]		offsets				= new float[4];
	private RescaleOp			rop;
	private BufferedImage		tmpbi;
	private Graphics2D			g2;

	public DrawCanvas( DrawApp a ) {
		app = a;
		rop = new RescaleOp( scales, offsets, null );
	}

	public void clear() {
		g2.clearRect( 0, 0, tmpbi.getWidth(), tmpbi.getHeight() );
	}

	public void drawLine( int x1, int y1, int x2, int y2 ) {
		g2.drawLine( x1, y1, x2, y2 );
	}

	public void setStrokeColor( Color c ) {
		g2.setColor( c );
	}

	public void fill( Shape s ) {
		g2.fill( s );
	}

	public void paintComponent( Graphics gr ) {
		Graphics2D g = (Graphics2D) gr;
		
		g.setBackground( getBackground() );
		g.clearRect( 0, 0, getWidth(), getHeight() );

		if( app.isSkinPrevious() )
			g.drawImage( app.getPreviousImage(), rop, 0, 0 );
		if( app.isSkinNext() ) g.drawImage( app.getNextImage(), rop, 0, 0 );

		g.drawImage( app.getImage(), 0, 0, null );

		g.drawImage( tmpbi, 0, 0, null );
	}

	@Override
	@Transient
	public Dimension getPreferredSize() {
		return app.getSize();
	}

	public void setSize( int w, int h ) {
		super.setSize( w, h );

		tmpbi = new BufferedImage( w, h, BufferedImage.TYPE_INT_ARGB );

		g2 = tmpbi.createGraphics();
		g2.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON );
		g2.setBackground( new Color( 0, 0, 0, 0 ) );
		g2.setColor( Color.black );
		g2.setPaint( Color.black );
	}

	public void setCursorSize( float size ) {
		int width = (int) Math.ceil( size );
		if( width < 2 ) width = 2;

		Toolkit tk = Toolkit.getDefaultToolkit();
		Dimension max = tk.getBestCursorSize( 999, 999 );
		if( width > max.width ) width = max.width;

		Dimension d = tk.getBestCursorSize( width, width );

		BufferedImage bi = new BufferedImage( d.width, d.height,
				BufferedImage.TYPE_INT_ARGB );
		Graphics2D g = bi.createGraphics();
		g.setRenderingHint( RenderingHints.KEY_ANTIALIASING,
				RenderingHints.VALUE_ANTIALIAS_ON );
		BasicStroke bs = new BasicStroke( .1f, BasicStroke.CAP_ROUND,
				BasicStroke.JOIN_ROUND );
		g.setStroke( bs );
		g.setColor( Color.BLACK );
		g.drawOval( 0, 0, width, width );
		g.dispose();

		width /= 2;
		if( width > d.width ) width = d.width;
		Cursor cursor = tk.createCustomCursor( bi, new Point( width, width ),
				"stylus" );

		this.setCursor( cursor );
	}

	public void setStroke( BasicStroke bs ) {
		g2.setStroke( bs );
	}
}
